﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lumo.display.animation2D
{
    /// <summary>
    /// A Parallel Animation class.
    /// </summary>
    public class ParallelAnimation2D : IInternalAnimation2D, IAnimation2D
    {
        // THe parent object
        private object CurrentObject = null;
        private List<IInternalAnimation2D> AnimationList = new List<IInternalAnimation2D>();
        private List<IInternalAnimation2D> OriginalAnimationList = new List<IInternalAnimation2D>();

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="CurrentObject">The animated object.</param>
        public ParallelAnimation2D(object CurrentObject = null)
        {
            // Set the object.
            this.CurrentObject = CurrentObject;
            this.Setupped = false;
        }

        /// <summary>
        /// Add an animation
        /// </summary>
        /// <param name="Animation">The animation to add.</param>
        public void Add(object Animation)
        {
            // Set the parent object.
            if (!(Animation is IInternalAnimation2D))
                throw new Exception("Animation is not valid");
            // Add the animation.
            else
                OriginalAnimationList.Add(Animation as IInternalAnimation2D);
        }

        /// <summary>
        /// Clear the animation.
        /// </summary>
        public void Clear()
        {
            // Set the parent object.
            OriginalAnimationList.Clear();
            AnimationList.Clear();
            this.Setupped = false;
        }

        /// <summary>
        /// Setup the animations.
        /// </summary>
        /// <param name="ParentObject">The parent object of the animations.</param>
        public void Setup(object ParentObject)
        {
            // Already setupped.
            if (this.Setupped)
                return;
            // Set the parent object.
            if (CurrentObject == null)
                CurrentObject = ParentObject;

            // Clear the animation list.
            AnimationList.Clear();
            foreach (IInternalAnimation2D anim in OriginalAnimationList)
                AnimationList.Add(anim);
            // The object is setupped.
            this.Setupped = true;
        }

        /// <summary>
        /// Reset the animations.
        /// </summary>
        public void Reset()
        {
            // Reset animations
            foreach (IInternalAnimation2D anim in AnimationList)
                anim.Reset();
            // Clear list.
            AnimationList.Clear();
            // Not setupped.
            this.Setupped = false;
        }

        /// <summary>
        /// Check if it is setupped.
        /// </summary>
        public bool Setupped { get; private set; }

        /// <summary>
        /// Check if animation has finished.
        /// </summary>
        /// <returns>True if it has</returns>
        public bool Finished
        {
            get
            {
                // Return only if all animations has finished.
                foreach (IAnimation2D anim in AnimationList)
                {
                    if (!anim.Finished)
                        return false;
                }
                return true;
            }
        }

        /// <summary>
        /// Update the animations.
        /// </summary>
        /// <param name="Game"></param>
        public void Update(LumoComponent Game)
        {
            if (!Setupped)
                this.Setup(CurrentObject);
            // Return only if all animations has finished.
            foreach (IInternalAnimation2D anim in AnimationList)
            {
                if (!anim.Setupped)
                    anim.Setup(CurrentObject);
                anim.Update(Game);
            }
            AnimationList.RemoveAll(anim => anim.Finished);
        }
    }
}
